home *** CD-ROM | disk | FTP | other *** search
- #ifdef SGI
- #include <gl/gl.h>
- #include "device.h"
- #else
- #include "vogl.h"
- #include "vodevice.h"
- #endif
-
- #include <math.h>
- #include <stdio.h>
-
- #define RADIUS 0.9
- #define TWOPI 6.28318530
- /*#define PI 3.14159265*/
-
- float blackvec[3] = {0.0, 0.0, 0.0}; /* black RGB */
- Matrix idmat = {1.0, 0.0, 0.0, 0.0, /* identity matrix */
- 0.0, 1.0, 0.0, 0.0,
- 0.0, 0.0, 1.0, 0.0,
- 0.0, 0.0, 0.0, 1.0};
-
- /* define a polygon with some structures */
- typedef struct
- {
- Coord x;
- Coord y;
- Coord z;
- } POINT;
-
- typedef struct
- { /* lighted polygon struct */
- POINT vertex[4];
- POINT normal[4];
- } POLYGON;
-
- int number_of_polys; /* cylinder polygon count */
- POLYGON *polygon; /* polygon list pointer */
-
- /* define property arrays */
- float shiny_material[] =
- {
- SPECULAR, 0.8, 0.8, 0.8, /* lt. gray reflectance */
- DIFFUSE, 0.4, 0.4, 0.4, /* gray reflectance */
- SHININESS, 30.0, /* focused highlight */
- LMNULL};
-
- float purple_material[] =
- {
- SPECULAR, 0.3, 0.3, 0.3, /* gray reflectance */
- DIFFUSE, 0.8, 0.0, 0.8, /* purple reflectance */
- SHININESS, 3.0, /* unfocused highlight */
- AMBIENT, 0.2, 0.2, 0.2, /* purple reflectance */
- LMNULL};
-
- float blue_light[] =
- {
- LCOLOR, 0.0, 0.0, 0.6, /* blue light */
- POSITION, 0.0, 0.1, 0.0, 0.0, /* Y axis at infinity */
- LMNULL};
-
- /*
- ** def_light_calc()
- ** Tell the Graphics Library to DEFINE a
- ** lighting calculation that accounts for
- ** ambient, diffuse, and specular reflection.
- ** This lighting calculation defines a second
- ** material and light source
- */
- def_light_calc()
- {
- lmdef(DEFMATERIAL, 1, 11, shiny_material);
- lmdef(DEFMATERIAL, 2, 15, purple_material);
- lmdef(DEFLIGHT, 1, 0, NULL);
- lmdef(DEFLIGHT, 2, 10, blue_light);
- lmdef(DEFLMODEL, 1, 0, NULL);
- }
-
- /*
- ** use_light_calc()
- ** Tell the Graphics Library to USE
- ** the lighting calculation that we
- ** defined earlier.
- */
- use_light_calc()
- {
- lmbind(LIGHT0, 1); /* use light source description 1 */
- lmbind(LIGHT1, 2); /* use light source description 2 */
- lmbind(LMODEL, 1); /* use lighting model 1 */
- };
-
- /*
- ** make_cylinder()
- ** Draw a cylinder using (2 * n) polygons
- ** to approximate the curvature and n polygons
- ** to describe the length. This requires (2 * n^2)
- ** polygons to describe the cylinder. Compute
- ** the surface normal at each vertex so we can
- ** use the hardware lighting facility to perform
- ** lighting calculations.
- */
- make_cylinder(n)
- int n;
- {
- POLYGON *p; /* polygon list pointer */
- float theta, dtheta, /* current angle and angle */
- /* increment around section */
- x, dx; /* current position and */
- /* increment along cylinder side */
- int vertex_i; /* vertex counter */
-
- /* allocate and point to enough */
- /* memory for all the polygons */
- number_of_polys = 2 * n * n;
- p = polygon = (POLYGON *)
- malloc(number_of_polys * sizeof(POLYGON));
-
- dx = 3.0 / n; /* n polygons for 3.0 units of length */
- dtheta = PI / n; /* length of polygon along curvature */
-
- /* for each layer of polygons */
- /* along length of cylinder ... */
- for (x = -1.5; x < 1.5; x = x + dx)
- {
- /* ... and for each polygon */
- /* describing the circumference */
- for (theta = 0.0; theta < TWOPI; theta += dtheta)
- {
- /* calculate the four points */
- /* describing the polygon */
- p->vertex[0].x = p->vertex[1].x = x;
- p->vertex[0].y = p->vertex[3].y =
- RADIUS * cos(theta);
- p->vertex[0].z = p->vertex[3].z =
- RADIUS * sin(theta);
- p->vertex[1].y = p->vertex[2].y =
- RADIUS * cos(theta + dtheta);
- p->vertex[1].z = p->vertex[2].z =
- RADIUS * sin(theta + dtheta);
- p->vertex[2].x = p->vertex[3].x = x + dx;
-
- /* calculate the four normals of unit length */
- for (vertex_i = 0; vertex_i < 4; vertex_i++)
- {
- p->normal[vertex_i].x = 0;
- p->normal[vertex_i].y =
- p->vertex[vertex_i].y / RADIUS;
- p->normal[vertex_i].z =
- p->vertex[vertex_i].z / RADIUS;
- }
- p++;
- if (qtest()) {
- qread(&val);
- gexit();
- exit(0);
- }
- }
- }
- }
-
-
- /*
- ** draw_cylinder()
- ** This subroutine increments through the 4
- ** vertices describing each polygon of the
- ** cylinder defined in make cylinder. Note
- ** how a normal is sent to the graphics
- ** hardware before each vertex so that the
- ** lighting facility will compute the color
- ** for each vertex based on the lighting
- ** parameters that we are using.
- */
- draw_cylinder()
- {
- POLYGON *p; /* pointer into polygon list */
- int poly_i; /* polygon counter */
-
- /* start at first polygon and */
- /* increment through all of them */
- p = polygon;
- for (poly_i = 0; poly_i < number_of_polys; poly_i++)
- {
- bgnpolygon(); /* describe the polygon */
- n3f(&p->normal[0]);
- v3f(&p->vertex[0]);
- n3f(&p->normal[1]);
- v3f(&p->vertex[1]);
- n3f(&p->normal[2]);
- v3f(&p->vertex[2]);
- n3f(&p->normal[3]);
- v3f(&p->vertex[3]);
- endpolygon();
- p++; /* go to the next polygon */
- }
- }
-
- /*
- ** Main Program
- */
- main()
- {
- int i;
-
- /* set up graphics environment */
- prefposition(0, 900, 0, 900);
- winopen("cylinder");
- RGBmode();
- doublebuffer();
- gconfig();
- zbuffer(TRUE);
-
- /* Use mmode to set up projection */
- /* and viewing matrices for lighting */
- mmode(MVIEWING);
- perspective(400, 1.0, 4.0, 12.0);
- loadmatrix(idmat);
- lookat(0.0, 0.0, 8.0, 0.0, 0.0, 0.0, 0);
-
- /* let there be light !!! */
- def_light_calc();
- use_light_calc();
-
- /* Rotate cylinders in 2 deg. increments */
- /* about the Y and Z axis for 180 frames */
- make_cylinder(25);
- for (i = 0; i < 180; i++)
- {
- c3f(blackvec);
- clear();
- zclear();
-
- pushmatrix();
- rot(i * 2.0, 'Z');
- rot(i * 2.0, 'Y');
-
- /* use white shiny material for cyl 1 */
- lmbind(MATERIAL, 1);
- draw_cylinder();
-
- pushmatrix();
- rot(90.0, 'Y');
- scale(0.9, 0.9, 0.9);
-
- /* use purple rough material for cyl 2 */
- lmbind(MATERIAL, 2);
- draw_cylinder();
-
- popmatrix();
- popmatrix();
- swapbuffers();
- }
- sleep(3);
- }
-